<?php 

require_once 'MainPageWidget.php';
class CommunityTdiEditWidget extends MainPageWidget
	/**
	 * Класс CommunityTdiEditWidget -- редактор разделов сообщества.
	 */
{
	public $title = 'Разделы сообщества';

	public $ajax_functions = array(
		'ajax_list',
		'ajax_moveTdi',
		'ajax_show_in_main_menu',

		'ajax_settings_form',
		'ajax_settings_submit',
	);
	public $widget_js_path = 'widget/preferences.js';
	
	
	private function ajax_init() {
		$operations = $this->acl_assistant->getAvailableOperations($community_oid);
		if ( !$this->acl_assistant->is_granted( array( "tdi_edit") ) ) return false;

		$this->am_tdis = $this->ctx->mm->getModel("Tdi", "m");
		$this->m_tdis = $this->ctx->mm->getModel("Tdi", "m");
	}

	public function ajax_list ()
	{
		$view = $this->getView('WG_TdiList/items');
		$this->renderWidget($view);

		$html = $view->getContent();
		$this->ctx->cp->set_data($html);
	} // end of function ajax_list

	public function ajax_show_in_main_menu ($tdi_id=NULL, $state=NULL)
	{
		if ($this->ajax_init()===false) return false;

		if (!isset($tdi_id)) {
			$tdi_id = $this->ctx->rh->REQUEST['tdi_oid'];
			$state = $this->ctx->rh->REQUEST['state'];
		}
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$res = $this->m_tdis->setShowInMainMenuState($tdi_id, $community_oid, $state);
		$status = $res ? 0 : -1;
		$this->ctx->cp->set_data($status);
	} // end of method ajax_show_in_main_menu
	
	public function ajax_moveTdi ($tdi_id=NULL, $direction=NULL)
	{
		if ($this->ajax_init()===false) return false;

		if (!isset($tdi_id)) {
			$tdi_id = $this->ctx->rh->REQUEST['tdi_oid'];
			$direction = $this->ctx->rh->REQUEST['direction'];
		}

		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		switch ($direction) {
			case -1: $res = $this->m_tdis->moveDown($tdi_id, $community_oid); break;
			case 1: $res = $this->m_tdis->moveUp($tdi_id, $community_oid); break;
			default: $res = false;
		}

		$status = $res ? 0 : -1;
		$this->ctx->cp->set_data($status);
	}

	public function ajax_settings_form ($tdi_id=NULL)
	{
		if (!isset($tdi_id)) {
			$tdi_id = $this->ctx->rh->REQUEST['tdi_oid'];
		}

		$this->getTdiSettings($tdi_id, $content);
		$this->getAccessSettings($tdi_id, $content);

		$view = $this->getView('WG_TdiList/form_tdi_settings');
		$view->data['widget'] = $content;
		if ($tdi_id) $view->data['event_edit'] = 1;
		$html = $view->getContent();

		$this->ctx->cp->set_data($html);
	} // end of function ajax_showSettingsForm
	
	public function ajax_settings_submit ($url)
	{
		$this->ajax_init();
		$info = php_parse_str($url);
		do {
			if ($errors = $this->validateSettings($info)) {
				$status = $errors;
				break;
			}
			if (!($tdi = $this->saveTdi($info))) {
				$status = 'Ошибка сохранения данных';
				break;
			}

			$info['tdi_id'] = $tdi->id;
			if (!($res = $this->saveTdiAccess($info))) {
				$status = 'Ошибка сохранения данных';
				break;
			}
			$status = 0;
		} while (false);
		$this->ctx->cp->set_data($status);
	} // end of function ajax_settings_submit

	public function validateSettingsTitle ($value, $hash)
	{
		if (empty($value)) {
			return 'Поле обязательно для заполнения';
		}
		if (mb_strlen($value) > 30) {
			return 'Значение слишком длинное';
		}
	} // end of method validateSettingsTitle
	
	public function validateSettingsUrl ($value, $hash)
	{
		$tdi_oid = $hash['oid'];
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$ql = 'select objects where 
			objects.oid != :1 
			and objects.is_deleted = 0
			and tdi.url = :0
			and tdi.community_oid = :2
			'
			;
		if ($tdi = $this->ctx->store->find($ql, array($value, $tdi_oid, $community_oid))->next()) {
			return 'Раздел с таким URL существует';
		}

		$reserved_worlds = array(
			// $ cat etc/conf.d/url.php | grep -E "'(path|act)'" | awk '{print $3}'|  sort | uniq | sort
			'ajax',
			'allcommunities',
			'chlogin',
			'comments_submit',
			'createcommunity',
			'createitem',
			'createtdi',
			'css',
			'del',
			'deletecomment',
			'deletecommunity',
			'deleteitem',
			'deletetdi',
			'edit',
			'editcomment',
			'edititem',
			'filestorage',
			'identity',
			'images',
			'imagestorage',
			'initdb',
			'join',
			'js',
			'login',
			'logout',
			'members',
			'profile',
			'showalphabet',
			'showfeed',
			'showfiles',
			'showforum',
			'showgallery',
			'showissue',
			'showissues',
			'test',
			'tmp',
			'tpl',
			'undel',
		);
		if (in_array($value, $reserved_worlds)) {
			return "URL уже используется";
		}

		if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $value)) {
			return "Ошибка в формате URL";
		}
	} // end of method validateSettingsUrl
	
	public function validateSettings ($hash)
	{
		$errors = array();
		foreach ($hash as $k=>$v) {
			$method = array($this, 'validateSettings'.$k);
			if (is_callable($method) && ($error = call_user_func($method, $v, $hash))) {
				$errors[$k] = $error;
			}
		}
		return $errors;
	} // end of method validateSettings

	public function render ()
	{
		$community_oid = $this->getParam('community_oid', $this->acl_assistant->acl_data['comity_oid']);
		$operations = $this->acl_assistant->getAvailableOperations();
		
		$tdi_nodes = $this->acl_assistant->getCommunityTdi($community_oid);
		$_tdis = array();
		if (isset($tdi_nodes)) {
			foreach ($tdi_nodes as $tdi_node) {		
				$_tdis[$tdi_node['id_object']] = $tdi_node;
			}
		}

		$tdis = array();
		if (empty($_tdis)) { // в сообществе (пока) нет разделов
		} else {
			
			foreach ($this->getDocTypes() as $i=>$dt) {
				$doctypes[$dt['value']] = $dt['title'];
			}
			
			foreach ($this->getFeedTypes() as $i=>$ft) {
				$feedtypes[$ft['value']] = $ft['title'];
			}
			
			$prefix = $this->ctx->db->db_prefix;
			$sql = "SELECT DISTINCT `{$prefix}objects`.*, count(afeed.oid) as items_count
			FROM `{$prefix}class_tdi`
			INNER JOIN `{$prefix}objects` ON store_objects.oid = `{$prefix}class_tdi`.oid
			INNER JOIN `{$prefix}class_tdi_order` ON `{$prefix}class_tdi_order`.oid=`{$prefix}class_tdi`.oid
			LEFT OUTER JOIN `{$prefix}class_allfeed` afeed ON afeed.tdi_oid = `{$prefix}class_tdi`.oid AND afeed.is_deleted = 0
			WHERE (`{$prefix}class_tdi`.`oid` IN (".implode(",", array_keys($_tdis)).") AND `{$prefix}objects`.`is_deleted` = 0) 
			GROUP BY `{$prefix}class_tdi`.`oid`
			ORDER BY `{$prefix}class_tdi_order`.`order` ASC";
			
			$rs = $this->store->findSQL($sql);
			$order = 1;
			while ($tdi = $rs->next()) {
				$row = $rs->rs->current();
				$t = $tdi->data;
				$t['oid'] = $tdi->id;
				$t['is_deleted'] = $tdi->is_deleted;
				$t['items_count'] = $row["items_count"];
				$t['actions']['move_up'] = ($order === 1 
					? false 
					: $this->getParam('widget_url').'&action=move_up&direction=-1&tdi_oid='.$tdi->id);
				$t['actions']['move_down'] = 
					$this->getParam('widget_url').'&action=move_down&direction=1&tdi_oid='.$tdi->id;
				$t['actions']['edit'] = 
					$this->getParam('widget_url').'&action=edit&tdi_oid='.$tdi->id;
				$t['actions']['show_in_main_menu'] = 
					$this->getParam('widget_url').'&action=show_in_main_menu&state=1&tdi_oid='.$tdi->id;
				$t['actions']['hide_in_main_menu'] = 
					$this->getParam('widget_url').'&action=show_in_main_menu&state=0&tdi_oid='.$tdi->id;
				$t['order'] = $order;
				
				$t['type_title'] = $doctypes[ $t['itype'] ];
				$t['feed_title'] = $feedtypes[ $t['view'] ];
				
				$tdis[] = $t;
				$order++;
			}
			if ($tdis) {
				$tdis[count($tdis)-1]['actions']['move_down'] = false;
			}
		}
		//$content['actions'] = array_fill_keys($operations, true);
		$this->actions = array_map('is_int', array_flip($operations));
		$this->actions['list'] = $this->getParam('widget_url');
		$this->actions['add'] = $this->getParam('widget_url');
		$this->items   = $tdis;

		return $this;
	} // end of function data

	public function loadCommunityRoles ($community_oid)
	{

		// выдернем роли для сообщества
		$community_roles = $this->acl_assistant->getRolesList($community_oid);

		// выдернем все роли
		$roles_ql = 'select objects where role.oid > 0 order by role.level';
		$rs = $this->store->find($roles_ql);
		if ($rs) {
			$roles = array();
			while ($role = $rs->next()) {
				$t = $role->data;
				$t['id'] = $role->id;
				$roles[$role->id] = $t;
			}
		}

		$members = array();
		// соберем данные по всем ролям в одни массив
		$users_role = array();
		foreach ($community_roles as $k=>$role) {
			$ro = $roles[$role['id_object']];
			if ($ro['name'] == 'administrator') {
				unset($community_roles[$k]);
			} else {
				$community_roles[$k]['title'] = $ro['title'];
				$community_roles[$k]['name'] = $ro['name'];
			}
		}

		return $community_roles;
	} // end of function loadCommunityRoles
	
	public function loadActionsForRoles ($object_oid, $roles)
	{
		foreach ($roles as $oid=>$role) {
			$actions = $this->acl_assistant->getAclbyRole($object_oid, $role['id_object']);
			$roles[$oid]['actions'] = $actions;
		}
		return $roles;
	} // end of function loadActionsForRoles
	
	public function loadActionsForTdi ($tdi_oid)
	{
		return $this->acl_assistant->listAcl($tdi_oid);
	} // end of function loadActionsForTdi
	
	// $action_list = $this->mergeDefaultAndValues($tdi_actions, $role['actions'], 'name', 'action');
	public function mergeDefaultAndValues ($defaults, $values, $key_name, $key_name_v=NULL)
	{
		$key_name = 'name';
		if (!isset($key_name_v)) $key_name_v = $key_name;
		$res = array();
		foreach ($defaults as $k=>$v) {
			$default = $v;
			$value   = NULL;
			$key = $default[$key_name];
			foreach ($values as $ak=>$av) {
				if ($av[$key_name_v] === $key) {
					$value = $av;
					break;
				}
			}
			$res[$key]['value'] = $value;
			$res[$key]['default'] = $default;
		}
		return $res;
	} // end of function mergeDefaultAndValues

	public function handle_init ($request)
	{
		global $FU;
		$ffull_path = $FU->dir->lib . '/templates2/js/preferences.js';

		$str = file_get_contents($ffull_path);
		$tpl_vars = array(
			'{{widget_id}}'  => $this->getParam('widget_id'),
			'{{widget_url}}' => $this->getParam('widget_url'),
		);
		//$str = strtr($str, $tpl_vars);
		$this->response->setContent($str);
		$this->response->getContent()->getMeta()->setMimeType('application/x-javascript');
		return $this->response;
	} // end of function handle_init

	public function getAccessSettings ($tdi_id, &$content)
	{
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$operations = $this->acl_assistant->getAvailableOperations();

		$community_roles = $this->loadCommunityRoles($community_oid);
		
		// HACK : 2008-02-05 : lucky
		// если tdi_id пуст
		$acl_object = $tdi_id ? $tdi_id : $community_oid;

		$community_roles = $this->loadActionsForRoles($acl_object, $community_roles);
		$tdi_actions     = $this->loadActionsForTdi($acl_object);

		foreach ($community_roles as $k=>$role) {
			$action_list = $this->mergeDefaultAndValues($tdi_actions, $role['actions'], 'name', 'action');
			$community_roles[$k]['action_list'] = $action_list;
		}

		$content['roles'] = $community_roles;
		$content['default']['tdi_actions'] = $tdi_actions;

		$tdi_nodes = $this->acl_assistant->getCommunityTdi($community_oid);

		$tdis = array();
		foreach ($tdi_nodes as $tdi_node) {
			$tdis[$tdi_node['id_object']] = $tdi_node;
		}
		if (array_key_exists($tdi_id, $tdis)) {
			$ql = 'select objects where tdi.oid = :0';
			$rs = $this->ctx->store->find($ql, array($tdi_id));
			$tdis = array();
			$tdi = $rs->next();
			$t = $tdi->data;
			$t['oid'] = $tdi->id;
			$content['data'] = $t;
		}

		$content['actions'] = array_map('is_int', array_flip($operations));//array_fill_keys($operations, true);
		$content['actions']['submit'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
		$content['actions']['edit_access'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
		$content['actions']['edit_settings'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
		$content['oid'] = $tdi_id;
	} // end of method getAccessSettings
	
	
	private function getDocTypes() {
		foreach ($this->ctx->doctypes as $doctype_name => $doctype_content) {
			if ($doctype_name !== 'comment') {
				$_dt = array();
				$_dt['title'] = $doctype_content['typename'];
				$_dt['value'] = $doctype_name;
				$doctypes[] = $_dt;
				unset($_dt);
			}
		}
		return $doctypes;
	}
	
	private function getFeedTypes() {
		 return array(
			array(
				'value' => 'showfeed',
				'title'=>'Лента'
			),
			array(
				'value' => 'showforum',
				'title'=>'Форум',
			),
			array(
				'value' => 'showalphabet',
				'title'=>'Алфавитный список',
			),
			array(
				'value' => 'showfiles',
				'title'=>'Файлы',
			),
			array(
				'value' => 'showgallery',
				'title'=>'Галерея',
			),
			array(
				'value' => 'showissues',
				'title'=>'Список выпусков',
			),

		);
	}
	
	public function getTdiSettings ($tdi_id, &$content)
	{
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$operations = $this->acl_assistant->getAvailableOperations();
		$tdi_nodes = $this->acl_assistant->getCommunityTdi($community_oid);

		$tdis = array();
		foreach ($tdi_nodes as $tdi_node) {
			$tdis[$tdi_node['id_object']] = $tdi_node;
		}
		if (array_key_exists($tdi_id, $tdis)) {
			$ql = 'select objects where tdi.oid = :0';
			$rs = $this->ctx->store->find($ql, array($tdi_id));
			$tdis = array();
			$tdi = $rs->next();
			$t = $tdi->data;
			$t['oid'] = $tdi->id;
			$content['data'] = $t;
		}
		
		$content['default']['itype'] = $this->getDocTypes();
		$content['default']['view'] = $this->getFeedTypes();
		$content['actions'] = array_map('is_int', array_flip($operations));//array_fill_keys($operations, true);
		$content['actions']['submit'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
		$content['actions']['edit_settings'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
		$content['actions']['edit_access'] = $this->getParam('widget_url').'&tdi_oid='.$tdi->id;
	} // end of method getTdiSettings

	public function saveTdi ($info)
	{
		$tdi = false;
		do {
			$acl_assistant = $this->acl_assistant;
			$community_oid = $this->acl_assistant->acl_data['comity_oid'];
			$info['community_oid'] = $community_oid;

			if (empty($info['oid'])) {
			// create TDI
				$operations = $acl_assistant->getAvailableOperations($community_oid);

				if (!$acl_assistant->is_granted( array( "tdi_create"))) {
					$tdi = false;
					break;
				}
				if (!($tdi = $this->m_tdis->createTdi($info))) {
					$tdi = false;
					break;
				}
				$acl_assistant->createTdi($community_oid, $tdi->id, $tdi->data['title']);
				$this->m_tdis->moveEnd($tdi->id, $community_oid);
			} else {
			// edit TDI
				$operations = $acl_assistant->getAvailableOperations($community_oid);

				if (!$acl_assistant->is_granted( array( "tdi_edit"))) {
					$tdi = false;
					break;
				}

				$tdi_oid = $info['oid']; unset($info['oid']);
				$tdi = $this->m_tdis->changeTdi( $tdi_oid, $info );
			}

		} while (false);

		return $tdi;
	} // end of method saveTdi
	
	public function saveTdiAccess ($info)
	{
		$acl_assistant = $this->acl_assistant;
		$community_oid = $this->acl_assistant->acl_data['comity_oid'];
		$tdi_id = $info['tdi_id'];

		// все роли сообщества
		$community_roles = $this->loadCommunityRoles($community_oid);
		// все возможные действия над tdi
		$tdi_actions     = $this->loadActionsForTdi($tdi_id);
		// их же имена
		$all_tdi_action_names = array_keys($tdi_actions);

		// теперь посмотрим что нам прислали
		$acls = array();
		$res = 0; // флаг ошибки
		foreach ($community_roles as $role) {
			$role_oid = $role['id_object'];
			foreach ($tdi_actions as $act_name => $act_data) {
				// нам прислали установки экшенов для данной роли
				if (isset($info['acl'][$role_oid][$act_name])) {
					$acls[$act_name] = 1;
				} else {
					// если нет -- запрещаем
					$acls[$act_name] = 0;
				}
			}
			
			if ($this->acl_assistant->updateAcl($tdi_id, $acls, $role_oid) > 0) {
				$res = 1;
			}
			
			unset($acls);
		}
		return $res;
	} // end of method saveTdiAccess
}

?>
